/**
 * 星空点击特效
 */

(function () {
    var Particles,
        bind = function (fn, me) {
            return function () {
                return fn.apply(me, arguments);
            };
        };

    Particles = (function () {
        function Particles() {
            this.render = bind(this.render, this);
            this.rotateRadians = bind(this.rotateRadians, this);
            this.random = bind(this.random, this);
            this.mouseMove = bind(this.mouseMove, this);
            this.mouseDown = bind(this.mouseDown, this);
            this.resize = bind(this.resize, this);
            this.animate = bind(this.animate, this);
            this.setStage = bind(this.setStage, this);
            this.setLighting = bind(this.setLighting, this);
            this.getTexture = bind(this.getTexture, this);
            this.addStars = bind(this.addStars, this);
            this.setActors = bind(this.setActors, this);
            this.getPastelColor = bind(this.getPastelColor, this);
            this.canvasMouse = {
                x: 0,
                y: 0,
                z: 0,
                px: 0,
                py: 0,
                py: 0,
                vx: 0,
                vy: 0,
                pressed: false
            };
            this.colors = ['#da6b00', '#8555d4', '#4ad3b5', '#ffffff'];
            this.particleCount = 500;
            this.initialRadius = 0.1;
            this.movementSpeed = 2;
            this.directions = [];
            this.starSystems = [];
            this.systemCount = 1;
            this.setStage();
            this.setLighting();
            this.setActors();
            setInterval((function (_this) {
                return function () {
                    _this.systemCount++;
                    return _this.addStars(_this.getPastelColor(), 0, 0);
                };
            })(this), 5000);
            this.animate();
            this.render();
        }

        Particles.prototype.getPastelColor = function () {
            this.col = new THREE.Color("hsl(" + (this.random(0, 360)) + ", " + (Math.floor(25 + 70 * Math.random())) + "%, " + (Math.floor(85 + 10 * Math.random())) + "%)");
            return "#" + (this.col.getHexString());
        };

        Particles.prototype.setActors = function () {
            return this.addStars(this.getPastelColor(), 0, 0);
        };

        Particles.prototype.addStars = function (color, x, y) {
            var angle, i, k, radiusSQ, ref, vertex;
            this.dirs = [];
            this.geometry = new THREE.Geometry();
            this.materials = new THREE.PointsMaterial({
                color: color,
                size: 1,
                transparent: true,
                blending: THREE.AdditiveBlending,
                map: this.getTexture(color),
                depthTest: false
            });
            for (i = k = 0, ref = this.particleCount; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) {
                angle = Math.random() * 2 * Math.PI;
                radiusSQ = Math.random() * this.initialRadius * this.initialRadius;
                vertex = new THREE.Vector3();
                vertex.x = x;
                vertex.y = y;
                vertex.z = 0;
                this.dirs.push({
                    x: (Math.random() * this.movementSpeed) - (this.movementSpeed / 2),
                    y: (Math.random() * this.movementSpeed) - (this.movementSpeed / 2),
                    z: (Math.random() * this.movementSpeed) - (this.movementSpeed / 2)
                });
                this.geometry.vertices.push(vertex);
            }
            this.starSystem = new THREE.Points(this.geometry, this.materials);
            this.starSystem.sortParticles = true;
            this.directions.push(this.dirs);
            this.starSystems.push(this.starSystem);
            return this.scene.add(this.starSystem);
        };

        Particles.prototype.getTexture = function (color) {
            var canvas, context, gradient, texture;
            canvas = document.createElement('canvas');
            canvas.width = 32;
            canvas.height = 32;
            context = canvas.getContext('2d');
            gradient = context.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2);
            gradient.addColorStop(0, 'rgba(255,255,255,1)');
            gradient.addColorStop(0.2, color);
            gradient.addColorStop(0.4, color);
            gradient.addColorStop(1, 'rgba(0,0,0,1)');
            context.fillStyle = gradient;
            context.fillRect(0, 0, canvas.width, canvas.height);
            texture = new THREE.Texture(canvas);
            texture.needsUpdate = true;
            return texture;
        };

        Particles.prototype.setLighting = function () {
            this.ambientLight = new THREE.AmbientLight("#ffffff", 0.5);
            return this.scene.add(this.ambientLight);
        };

        Particles.prototype.setStage = function () {
            this.renderer = new THREE.WebGLRenderer({
                canvas: document.getElementById("canvas"),
                antialias: true
            });
            this.renderer.setPixelRatio(window.devicePixelRatio);
            this.renderer.autoClear = false;
            this.renderer.setSize(window.innerWidth, window.innerHeight);
            this.scene = new THREE.Scene();
            this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
            this.camera.position.z = 50;
            this.stats = new Stats();
            this.stats.setMode(0);
            this.stats.domElement.style.position = 'absolute';
            this.stats.domElement.style.left = '0px';
            this.stats.domElement.style.top = '0px';
            document.getElementById("stats").appendChild(this.stats.domElement);
            window.addEventListener('resize', this.resize, false);
            window.addEventListener('mousemove', this.mouseMove, false);
            return window.addEventListener("mousedown", this.mouseDown);
        };

        Particles.prototype.animate = function () {
            var i, j, k, l, particle, ref, ref1;
            for (j = k = 0, ref = this.systemCount - 1; 0 <= ref ? k <= ref : k >= ref; j = 0 <= ref ? ++k : --k) {
                for (i = l = 0, ref1 = this.particleCount; 0 <= ref1 ? l < ref1 : l > ref1; i = 0 <= ref1 ? ++l : --l) {
                    particle = this.starSystems[j].geometry.vertices[i];
                    particle.x += this.directions[j][i].x;
                    particle.y += this.directions[j][i].y;
                    particle.z += this.directions[j][i].z;
                }
                this.starSystems[j].geometry.verticesNeedUpdate = true;
            }
            this.stats.update();
            this.render();
            return requestAnimationFrame(this.animate);
        };

        Particles.prototype.resize = function () {
            this.camera.aspect = window.innerWidth / window.innerHeight;
            this.camera.updateProjectionMatrix();
            this.renderer.setSize(window.innerWidth, window.innerHeight);
            return this.render();
        };

        Particles.prototype.mouseDown = function () {
            this.systemCount++;
            return this.addStars(this.getPastelColor(), this.canvasMouse.x, this.canvasMouse.y);
        };

        Particles.prototype.mouseMove = function () {
            this.canvasMouse.px = this.canvasMouse.x;
            this.canvasMouse.py = this.canvasMouse.y;
            this.canvasX = (event.clientX / window.innerWidth) * 2 - 1;
            this.canvasY = -(event.clientY / window.innerHeight) * 2 + 1;
            this.vector = new THREE.Vector3(this.canvasX || 0, this.canvasY || 0, 0);
            this.vector.unproject(this.camera);
            this.dir = this.vector.sub(this.camera.position).normalize();
            this.distance = -this.camera.position.z / this.dir.z;
            return this.canvasMouse = this.camera.position.clone().add(this.dir.multiplyScalar(this.distance));
        };

        Particles.prototype.random = function (min, max) {
            return Math.floor(Math.random() * max) + min;
        };

        Particles.prototype.rotateRadians = function (deg) {
            return deg * (Math.PI / 180);
        };

        Particles.prototype.render = function () {
            return this.renderer.render(this.scene, this.camera);
        };

        return Particles;

    })();

    new Particles;

}).call(this);